package main

import (
	"flag"
	"html/template"
	"log"
	"net/http"
)

var addr = flag.String("addr", ":1718", "http service address") // Q=17, R=18

var templ = template.Must(template.New("qr").Parse(templateStr))

func main() {
	flag.Parse()
	http.Handle("/", http.HandlerFunc(QR))
	err := http.ListenAndServe(*addr, nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func QR(w http.ResponseWriter, req *http.Request) {
	templ.Execute(w, req.FormValue("s"))
}

const templateStr = `
<html>
<head>
<title>QR Link Generator</title>
</head>
<body>
{{if .}}
<img src="http://chart.apis.google.com/chart?chs=300x300&cht=qr&choe=UTF-8&chl={{.}}" />
<br>
{{.}}
<br>
<br>
{{end}}
<form action="/" name=f method="GET">
    <input maxLength=1024 size=70 name=s value="" title="Text to QR Encode">
    <input type=submit value="Show QR" name=qr>
</form>
</body>
</html>
`

// 在 `main` 函数之前的部分应该很容易理解。这里通过一个命令行标志为服务器设置了默认的 HTTP 端口。
//`template` 变量 `templ` 才是关键所在。它构建了一个 HTML 模板，服务器会执行这个模板来显示页面，稍后会详细介绍。

// `main` 函数会解析命令行标志，然后使用我们前面提到的机制，将 `QR` 函数绑定到服务器的根路径。接着调用 `http.ListenAndServe` 来启动服务器，该函数会在服务器运行期间一直阻塞。

// `QR` 函数只是接收包含表单数据的请求，然后针对表单中名为 `s` 的值执行模板。

// `html/template` 包功能强大，这个程序只是触及了它的部分能力。
// 本质上，它会动态重写一段 HTML 文本，方法是用传递给 `templ.Execute` 的数据项替换其中的元素，
// 在这个例子中就是表单值。在模板文本（`templateStr`）里，用双花括号分隔的部分表示模板动作。
// 从 `{{if .}}` 到 `{{end}}` 这部分代码只有在当前数据项（用 `.` 表示）的值非空时才会执行。
//也就是说，当字符串为空时，模板的这部分内容不会显示。

// 两个 `{{.}}` 片段表示在网页上显示传递给模板的数据（即查询字符串）。
// `html/template` 包会自动进行适当的转义处理，确保文本可以安全显示。

// 模板字符串的其余部分就是页面加载时要显示的 HTML 内容。如果这个解释过于简略，可以查看 `template` 包的文档以获得更详尽的讨论。

// 就这样，几行代码加上一些数据驱动的 HTML 文本就实现了一个实用的 Web 服务器。Go 语言功能强大，几行代码就能实现很多功能。
